為什麽說 Class 是語法糖呢? 因為 Class 只是被包裝得好看的 Prototype-Based 而已
Class-Based 像是 Java, C++:
Prototype-Based 像是 Javascript:
那為什麼 ES6 要新增 Class ? 它只是為了提供更簡單的語法來創立物件跟繼承物件。
以下會用 ES5 跟 ES6 的語法分別來實作,這兩段的語法事實上是一樣的:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function() {
console.log(`Hello My name is ${this.name} and I'm ${this.age} years old`);
}
var Jay = new Person('Jay', 23);
Jay.sayHi(); // Hello My name is Jay and I'm 23 years old.
class PersonES6 {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(`Hello My name is ${this.name} and I'm ${this.age} years old`);
}
}
var Jay = new PersonES6('Jay', 23);
Jay.sayHi(); // Hello My name is Jay and I'm 23 years old.
constructor 是類別的默認方法,就算沒有定義,也一樣會產生一個空的 constructor
class Person {}
// 等同於
class Person {
constructor() {}
}
class Square {
constructor(width) {
this.width = width;
this.height = width;
}
get area() {
return this.width*this.height;
}
set area(area) {
this.width = Math.sqrt(area);
this.height = Math.sqrt(area);
}
}
let square1 = new Square(5);
console.log(square1); //{height: 5, width: 5}
console.log(square1.area); //25
square1.area = 4;
console.log(square1); //{height: 2, width: 2}
靜態方法(static)不會繼承或創立到物件上,只有原型才能使用,而且可以和 非靜態方法 重複命名。
這裡要注意,並沒有靜態屬性。
class Point {
static getX() {
console.log('get static X');
}
static getY(){
console.log('get static Y');
}
getY(){
console.log('get Y');
}
}
let point = new Point();
Point.getX(); // "get static X"
point.getY(); // "get Y"
ES6 class 可以透過 extends 實現繼承,ES5 則是先創造實例(instance)的this,然後再將父母類別添加到this上面(父母類別.apply(this, parameters))
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
class ShapePoint extends Point {
constructor(x, y, shape) {
super(x, y); // 調用父母類別的 x, y
this.shape = shape;
}
}
如果子類別沒有定義 constructor,會默認添加 ...args
class ShapePoint extends Point{}
//等同於
class ShapePoint extends Point {
constructor(...args) {
super(...args);
}
}
function Person(name,age) {
this.name = name;
this.age = age;
}
Person.prototype.sendBasicInfo = function() {
console.log(`My name is ${this.name} and ${this.age} years old.`);
}
function Student(name, age, school, classroom){
Person.apply(this, [name, age]);
this.school = school;
this.classroom = classroom;
}
// 繼承 Person.prototype 物件方法
Student.prototype = Object.create(Person.prototype);
Student.prototype.studyHard = function() {
console.log('I need to study hard');
}
var student1 = new Student('student1', 23, 'school', '1-1');
console.log(student1.sendBasicInfo()); // My name is student1 and 23 years old.
console.log(student1.studyHard()); // I need to study hard
class Person{
constructor(name, age) {
this.name = name;
this.age = age;
}
sendBasicInfo() {
console.log(`My name is ${this.name} and ${this.age} years old.`);
}
}
class Student extends Person{
constructor(name, age, school, classroom){
super(name, age, school);
this.school = school;
this.classroom = classroom;
}
studyHard() {
console.log('I need to study hard');
}
}
var student1 = new Student('student1', 23, 'school', '1-1');
console.log(student1.sendBasicInfo()); // My name is student1 and 23 years old.
console.log(student1.studyHard()); // I need to study hard
明天是禮拜一啊,不想上班哈哈